package com.momoc.mrpc.rpc.serialize;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import org.springframework.stereotype.Component;

import javax.print.DocFlavor;


/**
 * @author momoc
 * @version 1.0
 * @className DefaultMRpcSerializeMode
 * @description
 * @date 2022/7/25 2:52 下午
 */

@Component
public class DefaultMRpcSerializeMode implements MRpcSerializeMode{


    @Override
    public <T> T toJava(Class<T> clazz,  byte[] bytes) {
        Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new ClassCodec()).create();
        String json = new String(bytes, StandardCharsets.UTF_8);
        return gson.fromJson(json, clazz);
    }

    @Override
    public <T> byte[] toSerialize(T obj) {
        Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new ClassCodec()).create();
        String json = gson.toJson(obj);
        return json.getBytes(StandardCharsets.UTF_8);
    }


    public <T> String toJSONString(T obj) {
        Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new ClassCodec()).create();
        String json = gson.toJson(obj);
        return json;
    }

    @Override
    public String getSerializeTypeString() {
        return "gson";
    }
    @Override
    public byte getSerializeTypeByte() {
        return 0;
    }

    class ClassCodec implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {

        @Override
        public Class<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            try {
                String str = json.getAsString();
                return Class.forName(str);
            } catch (ClassNotFoundException e) {
                throw new JsonParseException(e);
            }
        }

        @Override             //   String.class
        public JsonElement serialize(Class<?> src, Type typeOfSrc, JsonSerializationContext context) {
            // class -> json
            return new JsonPrimitive(src.getName());
        }
    }
}
